package org.rooster.chromosomeevaluator.rules;

import org.jgap.IChromosome;
import org.rooster.chromosomeevaluator.common.ScheduleMetrix;
import org.rooster.genetic.GenericRule;
import org.rooster.manager.ResourceManager;
import org.rooster.manager.TaskManager;

import java.util.ArrayList;

/**
 * Created by IntelliJ IDEA.
 * User: manorama
 * Date: 7/22/12
 * Time: 11:22 AM
 * To
 * change this template use File | Settings | File Templates.
 */
public class ShiftLengthNotWithinMinMaxRangePenaltyRule implements GenericRule {

    private int weight = 1;
    private ArrayList<int[]> ruleViolations = new ArrayList<int[]>();

    public ShiftLengthNotWithinMinMaxRangePenaltyRule() {
    }

    public ShiftLengthNotWithinMinMaxRangePenaltyRule(int weight) {
        this.weight = weight;
    }

    @Override
    public double fitnessValueForRule(IChromosome chromosome) {
        double penalty = 1;
//        int timeSlotStartIndex;
//        int timeSlotEndIndex;
//        int employeeId;
        int assignmentCount;
//
//        int employeeAssignments[][] = new int[ResourceManager.TOTAL_NO_OF_EMPLOYEES][TaskManager.NO_OF_TIME_SLOTS];
        int employeeAssignments[][] = ScheduleMetrix.getScheduleMetrixInstance().getScheduleMetrixArray();
//        Gene[] genes = chromosome.getGenes();
//
//        for (int i=0; i< TaskManager.NO_OF_SECTIONS; i++) {
//            for (int j=0; j< TaskManager.NO_OF_TIME_SLOTS; j++) {
//                timeSlotStartIndex = GeneIndex.getTimeSlotStart(i, j);
//                timeSlotEndIndex = GeneIndex.getTimeSlotEnd(i, j);
//                for (int k=timeSlotStartIndex; k<=timeSlotEndIndex; k++) {
//                    employeeId = (Integer)genes[k].getAllele();
//                    employeeAssignments[employeeId-1][j] = 1; //put 1 to indicate the employee is assigned for work in this time slot
//                }
//            }
//        }

        for (int i = 0; i < employeeAssignments.length; i++) {
            assignmentCount = 0;
            for (int j = 0; j < TaskManager.NO_OF_TIME_SLOTS; j++) {
                if (employeeAssignments[i][j] != 0) {
                    assignmentCount++;
                } else {        //if this slot is free
                    if (notWithinShiftLengthMinMaxRange(assignmentCount)) {
                        penalty++;
                        ruleViolations.add(new int[]{i, (j - 1), assignmentCount});
                    }
                    assignmentCount = 0;
                }
            }
            if (notWithinShiftLengthMinMaxRange(assignmentCount)) {
                penalty++;
                ruleViolations.add(new int[]{i, 7, assignmentCount});
            }
        }
        return 1.0 / (penalty * weight);
    }

    private boolean notWithinShiftLengthMinMaxRange(int assignmentCount) {
        if (assignmentCount != 0 && (assignmentCount < ResourceManager.MIN_SHIFT_LENGTH || assignmentCount > ResourceManager.MAX_SHIFT_LENGTH)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public int getWeight() {
        return weight;
    }

    @Override
    public void setWeight(int value) {
        this.weight = value;
    }

    /**
     * @return the ruleViolations
     */
    public ArrayList<int[]> getRuleViolations() {
        return ruleViolations;
    }
}
